/*
 * Copyright (c) 2008 Benoit Bouchez, Nicolas Giard
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.noocodecommit.wicket.stuff.jquery.plugin.ui.dialog;

import java.util.HashMap;
import java.util.Iterator;

import com.noocodecommit.wicket.stuff.jquery.plugin.JQPluginOptions;

/**
 * JQAccordion Option set
 * 
 * @author Benoit Bouchez
 * 
 */
public class JQDialogOptions extends JQPluginOptions implements Cloneable
{
	/** center position value */
	public static final String POSITION_CENTER = "center";
	/** left position value */
	public static final String POSITION_LEFT = "left";
	/** right position value */
	public static final String POSITION_RIGHT = "right";
	/** top position value */
	public static final String POSITION_TOP = "top";

	private boolean autoOpen = true;
	private boolean draggable = true;
	private boolean modal = false;
	private boolean resizable = true;
	private boolean stack = true;
	private HashMap<String, String> buttons = new HashMap<String, String>();
	private String dialogClass;
	private String hide = "";
	private String show = "";
	private String title = "";
	private String overlay = "{}";
	private int width = 300;
	private int minWidth = 150;
	private int maxWidth;
	private int height = 200;
	private int minHeight = 100;
	private int maxHeight;
	private Object[] position = { POSITION_CENTER, POSITION_CENTER };

	private String openScript = "";
	private String focusScript = "";
	private String closeScript = "";
	private String dragStartScript = "";
	private String dragScript = "";
	private String dragStopScript = "";
	private String resizeStartScript = "";
	private String resizeScript = "";
	private String resizeStopScript = "";

	/**
	 * Constructor
	 */
	public JQDialogOptions()
	{
		super();
		this.setDefaultHeader("dialog");
	}

	/**
	 * Gets the auto open value
	 * 
	 * @return the auto open value
	 */
	public boolean isAutoOpen()
	{
		return autoOpen;
	}

	/**
	 * Sets the autoOpen option value
	 * 
	 * @param autoOpen
	 *            dialog autoOpen
	 */
	public void setAutoOpen(boolean autoOpen)
	{
		this.autoOpen = autoOpen;
		this.options.put("autoOpen", "autoOpen:" + autoOpen);
	}

	/**
	 * Gets the draggable value
	 * 
	 * @return the draggable value
	 */
	public boolean isDraggable()
	{
		return draggable;
	}

	/**
	 * Sets the draggable option value
	 * 
	 * @param draggable
	 *            dialog draggable
	 */
	public void setDraggable(boolean draggable)
	{
		this.draggable = draggable;
		this.options.put("draggable", "draggable:" + draggable);
	}

	/**
	 * Gets the modal value
	 * 
	 * @return the modal value
	 */
	public boolean isModal()
	{
		return modal;
	}

	/**
	 * Sets the modal option value
	 * 
	 * @param modal
	 *            dialog modal
	 */
	public void setModal(boolean modal)
	{
		this.modal = modal;
		this.options.put("modal", "modal:" + modal);
	}

	/**
	 * Gets the resizable value
	 * 
	 * @return the resizable value
	 */
	public boolean isResizable()
	{
		return resizable;
	}

	/**
	 * Sets the resizable option value
	 * 
	 * @param resizable
	 *            dialog resizable
	 */
	public void setResizable(boolean resizable)
	{
		this.resizable = resizable;
		this.options.put("resizable", "resizable:" + resizable);
	}

	/**
	 * Gets the stack value
	 * 
	 * @return the stack value
	 */
	public boolean isStack()
	{
		return stack;
	}

	/**
	 * Sets the stack option value
	 * 
	 * @param stack
	 *            dialog stack
	 */
	public void setStack(boolean stack)
	{
		this.stack = stack;
		this.options.put("stack", "stack:" + stack);
	}

	/**
	 * Gets the dialog class value
	 * 
	 * @return the dialog class value
	 */
	public String getDialogClass()
	{
		return dialogClass;
	}

	/**
	 * Sets the dialogClass option value
	 * 
	 * @param dialogClass
	 *            dialog dialogClass
	 */
	public void setDialogClass(String dialogClass)
	{
		this.dialogClass = dialogClass;
		this.options.put("dialogClass", "dialogClass:'" + dialogClass + "'");
	}

	/**
	 * Gets the hide animation value
	 * 
	 * @return the hide animation value
	 */
	public String getHide()
	{
		return hide;
	}

	/**
	 * Sets the hide animation option value
	 * 
	 * @param hide
	 *            dialog hide animation
	 */
	public void setHide(String hide)
	{
		this.hide = hide;
		this.options.put("hide", "hide:'" + hide + "'");
	}

	/**
	 * Gets the show animation value
	 * 
	 * @return the show animation value
	 */
	public String getShow()
	{
		return show;
	}

	/**
	 * Sets the show animation option value
	 * 
	 * @param show
	 *            dialog show animation
	 */
	public void setShow(String show)
	{
		this.show = show;
		this.options.put("show", "show:'" + show + "'");
	}

	/**
	 * Gets the title value
	 * 
	 * @return the title value
	 */
	public String getTitle()
	{
		return title;
	}

	/**
	 * Sets the title option value
	 * 
	 * @param title
	 *            dialog title
	 */
	public void setTitle(String title)
	{
		this.title = title;
		this.options.put("title", "title:'" + title + "'");
	}

	/**
	 * Gets the overlay value
	 * 
	 * @return the overlay value
	 */
	public String getOverlay()
	{
		return overlay;
	}

	/**
	 * Sets the overlay option value
	 * 
	 * @param overlay
	 *            dialog overlay
	 */
	public void setOverlay(String overlay)
	{
		this.overlay = overlay;
		this.options.put("overlay", "overlay:'" + overlay + "'");
	}

	/**
	 * Gets the width value
	 * 
	 * @return the width value
	 */
	public int getWidth()
	{
		return width;
	}

	/**
	 * Sets the width option value
	 * 
	 * @param width
	 *            dialog width
	 */
	public void setWidth(int width)
	{
		this.width = width;
		this.options.put("width", "width:" + width);
	}

	/**
	 * Gets the min width value
	 * 
	 * @return the min width value
	 */
	public int getMinWidth()
	{
		return minWidth;
	}

	/**
	 * Sets the min width option value
	 * 
	 * @param minWidth
	 *            dialog min width
	 */
	public void setMinWidth(int minWidth)
	{
		this.minWidth = minWidth;
		this.options.put("minWidth", "minWidth:" + minWidth);
	}

	/**
	 * Gets the max width value
	 * 
	 * @return the max width value
	 */
	public int getMaxWidth()
	{
		return maxWidth;
	}

	/**
	 * Sets the max width option value
	 * 
	 * @param maxWidth
	 *            dialog max width
	 */
	public void setMaxWidth(int maxWidth)
	{
		this.maxWidth = maxWidth;
		this.options.put("maxWidth", "maxWidth:" + maxWidth);
	}

	/**
	 * Gets the height value
	 * 
	 * @return the height value
	 */
	public int getHeight()
	{
		return height;
	}

	/**
	 * Sets the height option value
	 * 
	 * @param height
	 *            dialog height
	 */
	public void setHeight(int height)
	{
		this.height = height;
		this.options.put("height", "height:" + height);
	}

	/**
	 * Gets the min height value
	 * 
	 * @return the min height value
	 */
	public int getMinHeight()
	{
		return minHeight;
	}

	/**
	 * Sets the min height option value
	 * 
	 * @param minHeight
	 *            dialog minHeight
	 */
	public void setMinHeight(int minHeight)
	{
		this.minHeight = minHeight;
		this.options.put("minHeight", "minHeight:" + minHeight);
	}

	/**
	 * Gets the max height value
	 * 
	 * @return the max height value
	 */
	public int getMaxHeight()
	{
		return maxHeight;
	}

	/**
	 * Sets the max height option value
	 * 
	 * @param maxHeight
	 *            dialog maxHeight
	 */
	public void setMaxHeight(int maxHeight)
	{
		this.maxHeight = maxHeight;
		this.options.put("maxHeight", "maxHeight:" + maxHeight);
	}

	/**
	 * Gets the position value
	 * 
	 * @return the position value
	 */
	public Object[] getPosition()
	{
		return position;
	}

	/**
	 * Sets the position option value
	 * 
	 * @param position
	 *            dialog position
	 */
	public void setPosition(Object[] position)
	{
		this.position = position;
		this.options.put("position", "position:[" + position[0] + "," + position[1] + "]");
	}

	/**
	 * Gets the open script value
	 * 
	 * @return the open script value
	 */
	public String getOpenScript()
	{
		return openScript;
	}

	/**
	 * Sets the open function
	 * 
	 * @param openScript
	 *            dialog open function
	 */
	public void setOpenScript(String openScript)
	{
		this.openScript = openScript;
		this.options.put("open", "open:function(type, data){" + openScript + "}");
	}

	/**
	 * Gets the focus script value
	 * 
	 * @return the focus script value
	 */
	public String getFocusScript()
	{
		return focusScript;
	}

	/**
	 * Sets the focus function
	 * 
	 * @param focusScript
	 *            dialog focus function
	 */
	public void setFocusScript(String focusScript)
	{
		this.focusScript = focusScript;
		this.options.put("focus", "focus:function(type, data){" + focusScript + "}");
	}

	/**
	 * Gets the close script value
	 * 
	 * @return the close script value
	 */
	public String getCloseScript()
	{
		return closeScript;
	}

	/**
	 * Sets the close function
	 * 
	 * @param closeScript
	 *            dialog close function
	 */
	public void setCloseScript(String closeScript)
	{
		this.closeScript = closeScript;
		this.options.put("close", "close:function(type, data){" + closeScript + "}");
	}

	/**
	 * Gets the drag start script value
	 * 
	 * @return the drag start script value
	 */
	public String getDragStartScript()
	{
		return dragStartScript;
	}

	/**
	 * Sets the dragStart function
	 * 
	 * @param dragStartScript
	 *            dialog drag start function
	 */
	public void setDragStartScript(String dragStartScript)
	{
		this.dragStartScript = dragStartScript;
		this.options.put("dragStart", "dragStart:function(){" + dragStartScript + "}");
	}

	/**
	 * Gets the drag script value
	 * 
	 * @return the drag script value
	 */
	public String getDragScript()
	{
		return dragScript;
	}

	/**
	 * Sets the drag function
	 * 
	 * @param dragScript
	 *            dialog drag function
	 */
	public void setDragScript(String dragScript)
	{
		this.dragScript = dragScript;
		this.options.put("drag", "drag:function(){" + dragScript + "}");
	}

	/**
	 * Gets the drag stop script value
	 * 
	 * @return the drag stop script value
	 */
	public String getDragStopScript()
	{
		return dragStopScript;
	}

	/**
	 * Sets the dragStop function
	 * 
	 * @param dragStopScript
	 *            dialog drag stop function
	 */
	public void setDragStopScript(String dragStopScript)
	{
		this.dragStopScript = dragStopScript;
		this.options.put("dragStop", "dragStop:function(){" + dragStopScript + "}");
	}

	/**
	 * Gets the resize start script value
	 * 
	 * @return the resize start script value
	 */
	public String getResizeStartScript()
	{
		return resizeStartScript;
	}

	/**
	 * Sets the resizeStart function
	 * 
	 * @param resizeStartScript
	 *            dialog resize start function
	 */
	public void setResizeStartScript(String resizeStartScript)
	{
		this.resizeStartScript = resizeStartScript;
		this.options.put("resizeStart", "resizeStart:function(){" + resizeStartScript + "}");
	}

	/**
	 * Gets the resize script value
	 * 
	 * @return the resize script value
	 */
	public String getResizeScript()
	{
		return resizeScript;
	}

	/**
	 * Sets the resize function
	 * 
	 * @param resizeScript
	 *            dialog resize function
	 */
	public void setResizeScript(String resizeScript)
	{
		this.resizeScript = resizeScript;
		this.options.put("resize", "resize:function(){" + resizeScript + "}");
	}

	/**
	 * Gets the resize stop script value
	 * 
	 * @return the resize stop script value
	 */
	public String getResizeStopScript()
	{
		return resizeStopScript;
	}

	/**
	 * Sets the resize stop function
	 * 
	 * @param resizeStopScript
	 *            dialog resize stop function
	 */
	public void setResizeStopScript(String resizeStopScript)
	{
		this.resizeStopScript = resizeStopScript;
		this.options.put("resizeStop", "resizeStop:function(){" + resizeStopScript + "}");
	}

	/**
	 * Adds a button to the dialog
	 * 
	 * @param key
	 *            button key (also text value)
	 * @param callback
	 *            callback function on button click
	 */
	public void addButton(String key, String callback)
	{
		this.buttons.put(key, callback);
		StringBuilder sb = new StringBuilder();
		if (this.buttons.size() > 0)
		{
			for (Iterator<String> i = this.buttons.keySet().iterator(); i.hasNext();)
			{
				String iKey = i.next();
				sb.append("'" + iKey + "':function(){" + this.buttons.get(iKey) + "},");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		this.options.put("buttons", "buttons:{" + sb.toString() + "}");
	}

	/**
	 * Removes the button with specified key from the dialog
	 * 
	 * @param key
	 *            button key
	 */
	public void removeButton(String key)
	{
		this.buttons.remove(key);
		StringBuilder sb = new StringBuilder();
		if (this.buttons.size() > 0)
		{
			for (Iterator<String> i = this.buttons.keySet().iterator(); i.hasNext();)
			{
				String iKey = i.next();
				sb.append("'" + iKey + "':function(){" + this.buttons.get(iKey) + "},");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		this.options.put("buttons", "buttons:{" + sb.toString() + "}");
	}

	protected void appendCallback(String key, String callback)
	{
		String newCallback = this.buttons.get(key) + ";" + callback;
		addButton(key, newCallback);
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException
	{
		JQDialogOptions clone = (JQDialogOptions)super.clone();
		return clone;
	}
}
